<!DOCTYPE html>
<html lang="en">

<head>
	<meta http-equiv="content-type" content="text/html; charset=utf-8">
	<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport">
	
	<!-- title -->
	
	<title>
	
		为什么需要Java内存模型 | 
	 
	对线面试官
	</title>
	
	<!-- keywords,description -->
	 
		<meta name="description" content="Java一线大厂面试" />
	

	<!-- favicon -->
	
	<link rel="shortcut icon" href="/luffy/favicon.ico">
	


	<!-- search -->
	<script>
		var searchEngine = "https://www.baidu.com/s?wd=";
		if(typeof searchEngine == "undefined" || searchEngine == null || searchEngine == ""){
			searchEngine = "https://www.google.com/search?q=";
		}
		var homeHost = "";
		if(typeof homeHost == "undefined" || homeHost == null || homeHost == ""){
			homeHost = window.location.host;
		}
	</script>


	
<link rel="stylesheet" href="/luffy/css/main.css">

	
<link rel="stylesheet" href="https://cdn.staticfile.org/font-awesome/4.7.0/css/font-awesome.min.css">

	
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@9.17.1/build/styles/darcula.min.css">

	
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.css">


	
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js"></script>

	
<script src="https://cdn.jsdelivr.net/gh/fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.js"></script>

	
<script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@9.17.1/build/highlight.min.js"></script>

	
<script src="https://cdn.jsdelivr.net/npm/jquery-pjax@2.0.1/jquery.pjax.min.js"></script>

	
<script src="/luffy/js/main.js"></script>

	
		
<script src="https://cdn.jsdelivr.net/npm/leancloud-storage/dist/av-min.js"></script>

		
<script src="https://cdn.jsdelivr.net/npm/valine@1.3.10/dist/Valine.min.js"></script>

	
	
<meta name="generator" content="Hexo 5.4.0"></head>

<body>
	<script>
var _hmt = _hmt || [];
(function() {
  var hm = document.createElement("script");
  hm.src = "https://hm.baidu.com/hm.js?3efe99c287df5a1d6f0d02d187e403c1";
  var s = document.getElementsByTagName("script")[0]; 
  s.parentNode.insertBefore(hm, s);
})();
</script>

<header id="header">
    <a id="title" target="_blank" rel="noopener" href="https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzU4NzA3MTc5Mg==&action=getalbum&album_id=1657204970858872832&scene=126#wechat_redirect" class="logo">对线面试官</a>

	<ul id="menu">
		
	

	

		<li class="menu-item">
			<a href="https://gitee.com/zhongfucheng/Java3y" class="menu-item-link" target="_blank">
				【戳这里】获取更多原创干货💪💪
			</a>
		</li>
		<li class="menu-item">
			<a href="https://gitee.com/zhongfucheng/Java3y" class="menu-item-link" target="_blank">
				<i class="fa fa-github fa-2x"></i>
			</a>
		</li>
	</ul>
</header>

	
<div id="sidebar">
	<button id="sidebar-toggle" class="toggle" ><i class="fa fa-arrow-right " aria-hidden="true"></i></button>
	
	<div id="site-toc">
		<input id="search-input" class="search-input" type="search" placeholder="按回车全站搜索">
		<div id="tree">
			

			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										00-面试前准备
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/10/30/00-%E9%9D%A2%E8%AF%95%E5%89%8D%E5%87%86%E5%A4%87/01.%E7%AE%80%E5%8E%86/">
										01.简历
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										01-Java基础
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/01-Java%E5%9F%BA%E7%A1%80/01.%20%E6%B3%A8%E8%A7%A3/">
										01. 注解
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/01-Java%E5%9F%BA%E7%A1%80/02.%20%E6%B3%9B%E5%9E%8B/">
										02. 泛型
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/01-Java%E5%9F%BA%E7%A1%80/03.%20JavaNIO/">
										03. JavaNIO
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/01-Java%E5%9F%BA%E7%A1%80/04.%20%E5%8F%8D%E5%B0%84%E5%92%8C%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86/">
										04. 反射和动态代理
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										02-Java并发
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/02-Java%E5%B9%B6%E5%8F%91/01.%20%E5%A4%9A%E7%BA%BF%E7%A8%8B%E5%9F%BA%E7%A1%80/">
										01. 多线程基础
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/02-Java%E5%B9%B6%E5%8F%91/02.%20CAS/">
										02. CAS
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/02-Java%E5%B9%B6%E5%8F%91/03.%20synchronized/">
										03. synchronized
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/02-Java%E5%B9%B6%E5%8F%91/04.%20AQS%E5%92%8CReentrantLock/">
										04. AQS和ReentrantLock
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/02-Java%E5%B9%B6%E5%8F%91/05.%20%E7%BA%BF%E7%A8%8B%E6%B1%A0/">
										05. 线程池
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/02-Java%E5%B9%B6%E5%8F%91/06.%20ThreadLocal/">
										06. ThreadLocal
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/02-Java%E5%B9%B6%E5%8F%91/07.%20CountDownLatch%E5%92%8CCyclicBarrier/">
										07. CountDownLatch和CyclicBarrier
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file active">
									<a href="/luffy/2021/08/19/02-Java%E5%B9%B6%E5%8F%91/08.%20%E4%B8%BA%E4%BB%80%E4%B9%88%E9%9C%80%E8%A6%81Java%E5%86%85%E5%AD%98%E6%A8%A1%E5%9E%8B/">
										08. 为什么需要Java内存模型
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/02-Java%E5%B9%B6%E5%8F%91/09.%20%E6%B7%B1%E5%85%A5%E6%B5%85%E5%87%BAJava%E5%86%85%E5%AD%98%E6%A8%A1%E5%9E%8B/">
										09. 深入浅出Java内存模型
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										03-Java容器
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/03-Java%E5%AE%B9%E5%99%A8/01.%20List%E9%9B%86%E5%90%88/">
										01. List集合
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/03-Java%E5%AE%B9%E5%99%A8/02.%20Map%E9%9B%86%E5%90%88/">
										02. Map集合
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										04-Java虚拟机
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/04-Java%E8%99%9A%E6%8B%9F%E6%9C%BA/01.%20Java%E7%BC%96%E8%AF%91%E5%88%B0%E6%89%A7%E8%A1%8C%E7%9A%84%E8%BF%87%E7%A8%8B/">
										01. Java编译到执行的过程
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/04-Java%E8%99%9A%E6%8B%9F%E6%9C%BA/02.%20%E5%8F%8C%E4%BA%B2%E5%A7%94%E6%B4%BE%E6%9C%BA%E5%88%B6/">
										02. 双亲委派机制
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/04-Java%E8%99%9A%E6%8B%9F%E6%9C%BA/03.%20JVM%E5%86%85%E5%AD%98%E7%BB%93%E6%9E%84/">
										03. JVM内存结构
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/04-Java%E8%99%9A%E6%8B%9F%E6%9C%BA/04.%20%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6%E6%9C%BA%E5%88%B6/">
										04. 垃圾回收机制
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/20/04-Java%E8%99%9A%E6%8B%9F%E6%9C%BA/05.%20CMS%E5%9E%83%E5%9C%BE%E6%94%B6%E9%9B%86%E5%99%A8/">
										05. CMS垃圾收集器
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/20/04-Java%E8%99%9A%E6%8B%9F%E6%9C%BA/06.%20G1%E5%9E%83%E5%9C%BE%E6%94%B6%E9%9B%86%E5%99%A8/">
										06. G1垃圾收集器
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/24/04-Java%E8%99%9A%E6%8B%9F%E6%9C%BA/07.%20JVM%E8%B0%83%E4%BC%98/">
										07. JVM调优
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										05-Spring
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/05-Spring/01.%20SpringMVC/">
										01. SpringMVC
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/05-Spring/02.%20Spring%E5%9F%BA%E7%A1%80/">
										02. Spring基础
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/05-Spring/03.%20SpringBean%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F/">
										03. SpringBean生命周期
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										06-Redis
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/06-Redis/01.%20Redis%E5%9F%BA%E7%A1%80/">
										01. Redis基础
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/06-Redis/02.%20Redis%E6%8C%81%E4%B9%85%E5%8C%96/">
										02. Redis持久化
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/20/06-Redis/03.%20Redis%E4%B8%BB%E4%BB%8E%E6%9E%B6%E6%9E%84/">
										03. Redis主从架构
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/20/06-Redis/04.%20Redis%E5%88%86%E7%89%87%E9%9B%86%E7%BE%A4/">
										04. Redis分片集群
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										07-消息队列
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/07-%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97/01.%20Kafka%E5%9F%BA%E7%A1%80/">
										01. Kafka基础
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/07-%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97/02.%20%E4%BD%BF%E7%94%A8Kafka%E4%BC%9A%E8%80%83%E8%99%91%E4%BB%80%E4%B9%88%E9%97%AE%E9%A2%98/">
										02. 使用Kafka会考虑什么问题
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										08-MySQL
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/08-MySQL/01.%20MySQL%E7%B4%A2%E5%BC%95/">
										01. MySQL索引
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/08-MySQL/02.%20MySQL%E4%BA%8B%E5%8A%A1%E5%92%8C%E9%94%81%E6%9C%BA%E5%88%B6%E5%92%8CMVCC/">
										02. MySQL事务和锁机制和MVCC
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/19/08-MySQL/03.%20MySQL%E8%B0%83%E4%BC%98/">
										03. MySQL调优
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										09-项目场景类
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/20/09-%E9%A1%B9%E7%9B%AE%E5%9C%BA%E6%99%AF%E7%B1%BB/01.%20%E5%A6%82%E4%BD%95%E5%AE%9E%E7%8E%B0%E5%8E%BB%E9%87%8D%E5%92%8C%E5%B9%82%E7%AD%89/">
										01. 如何实现去重和幂等
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/20/09-%E9%A1%B9%E7%9B%AE%E5%9C%BA%E6%99%AF%E7%B1%BB/02.%20%E7%B3%BB%E7%BB%9F%E9%9C%80%E6%B1%82%E5%A4%9A%E5%8F%98%E5%A6%82%E4%BD%95%E8%AE%BE%E8%AE%A1/">
										02. 系统需求多变如何设计
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/20/09-%E9%A1%B9%E7%9B%AE%E5%9C%BA%E6%99%AF%E7%B1%BB/03.%20%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/">
										03. 设计模式
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										10-计算机网络
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/08/25/10-%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/01.%20HTTP/">
										01. HTTP
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/10/13/10-%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/02.TCP%E4%B8%89%E6%AC%A1%E6%8F%A1%E6%89%8B%E5%92%8C%E5%9B%9B%E6%AC%A1%E6%8C%A5%E6%89%8B/">
										02.TCP三次握手和四次挥手
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										11-算法
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/09/01/11-%E7%AE%97%E6%B3%95/01.%20%E6%8E%92%E5%BA%8F%E7%AE%97%E6%B3%95/">
										01. 排序算法
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/09/02/11-%E7%AE%97%E6%B3%95/02.%20LeetCode%20Easy/">
										02. LeetCode Easy
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/09/02/11-%E7%AE%97%E6%B3%95/02.%20LeetCode%20Medium/">
										02. LeetCode Medium
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
							<ul>
								<li class="directory">
									<a href="#" class="directory">
										<i class="fa fa-plus-square-o"></i>
										12-austin项目
									</a>
									
							<ul>
								<li class="file">
									<a href="/luffy/2021/11/01/12-austin%E9%A1%B9%E7%9B%AE/00.%E9%A1%B9%E7%9B%AE%E4%BB%8B%E7%BB%8D/">
										00.项目介绍
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/10/30/12-austin%E9%A1%B9%E7%9B%AE/01.%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA/">
										01.环境搭建
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/10/30/12-austin%E9%A1%B9%E7%9B%AE/02.%E6%97%A5%E5%BF%97/">
										02.日志
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/11/24/12-austin%E9%A1%B9%E7%9B%AE/03.%E5%B7%A5%E5%85%B7%E5%8C%85/">
										03.工具包
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/11/24/12-austin%E9%A1%B9%E7%9B%AE/04.%E4%BB%8E%E4%B8%80%E6%9D%A1%E7%9F%AD%E4%BF%A1%E5%BC%80%E5%A7%8B/">
										04.从一条短信开始
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/11/24/12-austin%E9%A1%B9%E7%9B%AE/05.%E9%80%89%E6%8B%A9%E6%95%B0%E6%8D%AE%E5%BA%93%E5%92%8C%E6%8A%80%E6%9C%AF%E9%80%89%E5%9E%8B/">
										05.选择数据库和技术选型
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/11/24/12-austin%E9%A1%B9%E7%9B%AE/06.MySQL%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA/">
										06.MySQL环境搭建
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
							<ul>
								<li class="file">
									<a href="/luffy/2021/11/24/12-austin%E9%A1%B9%E7%9B%AE/07.Kafka%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA/">
										07.Kafka环境搭建
									</a>
								</li>
								<div class="article-toc" style="display: none;"></div>
							</ul>
			
								</li>
								
							</ul>
			
		</div>
	</div>
</div>

	<!-- 引入正文 -->
	<div id="content">
		<h1 id="article-title">

	08. 为什么需要Java内存模型
</h1>
<div class="article-meta">
	
	<span>3y</span>
	<span>2021-08-19 16:47:42</span>
		<div id="article-categories">
    
		<span>Categories：</span>
            
    

    
		<span>Tags：</span>
            
    
		</div>

</div>

<div id="article-content">
	<p><span style="color:#ab4642"><strong>面试官</strong></span>：<strong>今天想跟你聊聊Java内存模型，这块你了解过吗？</strong></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：嗯，我简单说下我的理解吧。那我就从为什么要有Java内存模型开始讲起吧</p>
<p><span style="color:#ab4642"><strong>面试官</strong></span>：开始你的表演吧。</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：那我先说下背景吧</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：1. 现有计算机往往是多核的，每个核心下会有高速缓存。高速缓存的诞生是由于「CPU与内存(主存)的速度存在差异」，L1和L2缓存一般是「每个核心独占」一份的。</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：2. 为了让CPU提高运算效率，处理器可能会对输入的代码进行「乱序执行」，也就是所谓的「指令重排序」</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：3. 一次对数值的修改操作往往是非原子性的（比如i++实际上在计算机执行时就会分成多个指令）</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：在永远单线程下，上面所讲的均不会存在什么问题，因为单线程意味着无并发。并且在单线程下，编译器/runtime/处理器都必须遵守as-if-serial语义，遵守as-if-serial意味着它们不会对「数据依赖关系的操作」做重排序。</p>
<p><img src="https://tva1.sinaimg.cn/large/008i3skNgy1gtt9cswjnrj6118078my802.jpg"></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：CPU为了效率，有了高速缓存、有了指令重排序等等，整块架构都变得复杂了。我们写的程序肯定也想要「充分」利用CPU的资源啊！于是乎，我们使用起了多线程</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：多线程在意味着并发，并发就意味着我们需要考虑线程安全问题</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：1. 缓存数据不一致：多个线程同时修改「共享变量」，CPU核心下的高速缓存是「不共享」的，那多个cache与内存之间的数据同步该怎么做？</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：2. CPU指令重排序在多线程下会导致代码在非预期下执行，最终会导致结果存在错误的情况。</p>
<p><img src="https://tva1.sinaimg.cn/large/008i3skNgy1gtt9ep8aqvj612k0ion1c02.jpg"></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：针对于「缓存不一致」问题，CPU也有其解决办法，常被大家所认识的有两种：</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：1.使用「总线锁」：某个核心在修改数据的过程中，其他核心均无法修改内存中的数据。（类似于独占内存的概念，只要有CPU在修改，那别的CPU就得等待当前CPU释放）</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：2.缓存一致性协议（MESI协议，其实协议有很多，只是举个大家都可能见过的）。MESI拆开英文是（Modified （修改状态）、Exclusive （独占状态）、Share（共享状态）、Invalid（无效状态））</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：缓存一致性协议我认为可以理解为「缓存锁」，它针对的是「缓存行」(Cache line) 进行”加锁”，所谓「缓存行」其实就是 高速缓存 存储的最小单位。</p>
<p><img src="https://tva1.sinaimg.cn/large/008i3skNgy1gtui35nzf9j60qk09sdgs02.jpg"></p>
<p><span style="color:#ab4642"><strong>面试官</strong></span>：嗯…</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：MESI协议的原理大概就是：当每个CPU读取共享变量之前，会先识别数据的「对象状态」(是修改、还是共享、还是独占、还是无效)。</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：如果是独占，说明当前CPU将要得到的变量数据是最新的，没有被其他CPU所同时读取</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：如果是共享，说明当前CPU将要得到的变量数据还是最新的，有其他的CPU在同时读取，但还没被修改</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：如果是修改，说明当前CPU正在修改该变量的值，同时会向其他CPU发送该数据状态为invalid(无效)的通知，得到其他CPU响应后（其他CPU将数据状态从共享(share)变成invalid(无效)），会当前CPU将高速缓存的数据写到主存，并把自己的状态从modify(修改)变成exclusive(独占)</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：如果是无效，说明当前数据是被改过了，需要从主存重新读取最新的数据。</p>
<p><img src="https://tva1.sinaimg.cn/large/008i3skNgy1gtuigrk9vvj60qc09qabk02.jpg"></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：其实MESI协议做的就是判断「对象状态」，根据「对象状态」做不同的策略。关键就在于某个CPU在对数据进行修改时，需要「同步」通知其他CPU，表示这个数据被我修改了，你们不能用了。</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：比较于「总线锁」，MESI协议的”锁粒度”更小了，性能那肯定会更高咯</p>
<p><span style="color:#ab4642"><strong>面试官</strong></span>：<strong>但据我了解，CPU还有优化，你还知道吗？</strong></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：嗯，还是了解那么一点点的。</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：从前面讲到的，可以发现的是：当CPU修改数据时，需要「同步」告诉其他的CPU，等待其他CPU响应接收到invalid(无效)后，它才能将高速缓存数据写到主存。</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：同步，意味着等待，等待意味着什么都干不了。CPU肯定不乐意啊，所以又优化了一把。</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：优化思路就是从「同步」变成「异步」。</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：在修改时会「同步」告诉其他CPU，而现在则把最新修改的值写到「store buffer」中，并通知其他CPU记得要改状态，随后CPU就直接返回干其他事了。等到收到其它CPU发过来的响应消息，再将数据更新到高速缓存中。</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：其他CPU接收到invalid(无效)通知时，也会把接收到的消息放入「invalid queue」中，只要写到「invalid queue」就会直接返回告诉修改数据的CPU已经将状态置为「invalid」</p>
<p><img src="https://tva1.sinaimg.cn/large/008i3skNgy1gtv3t52ts2j60t20baab202.jpg"></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：而异步又会带来新问题：那我现在CPU修改完A值，写到「store buffer」了，CPU就可以干其他事了。那如果该CPU又接收指令需要修改A值，但上一次修改的值还在「store buffer」中呢，没修改至高速缓存呢。</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：所以CPU在读取的时候，需要去「store buffer」看看存不存在，存在则直接取，不存在才读主存的数据。【Store Forwarding】</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：好了，解决掉第一个异步带来的问题了。（相同的核心对数据进行读写，由于异步，很可能会导致第二次读取的还是旧值，所以首先读「store buffer」。</p>
<p><span style="color:#ab4642"><strong>面试官</strong></span>：<strong>还有其他？</strong></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：那当然啊，那「异步化」会导致相同核心读写共享变量有问题，那当然也会导致「不同」核心读写共享变量有问题啊</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：CPU1修改了A值，已把修改后值写到「store buffer」并通知CPU2对该值进行invalid(无效)操作，而CPU2可能还没收到invalid(无效)通知，就去做了其他的操作，导致CPU2读到的还是旧值。</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：即便CPU2收到了invalid(无效)通知，但CPU1的值还没写到主存，那CPU2再次向主存读取的时候，还是旧值…</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：变量之间很多时候是具有「相关性」(a=1;b=0;b=a)，这对于CPU又是无感知的…</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：总体而言，由于CPU对「缓存一致性协议」进行的异步优化「store buffer」「invalid queue」，很可能导致后面的指令很可能查不到前面指令的执行结果（各个指令的执行顺序非代码执行顺序），这种现象很多时候被称作「CPU乱序执行」</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：为了解决乱序问题（也可以理解为可见性问题，修改完没有及时同步到其他的CPU），又引出了「内存屏障」的概念。</p>
<p><img src="https://tva1.sinaimg.cn/large/008i3skNgy1gtv3twpklaj60po0ekwfw02.jpg"></p>
<p><span style="color:#ab4642"><strong>面试官</strong></span>：嗯…</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：「内存屏障」其实就是为了解决「异步优化」导致「CPU乱序执行」/「缓存不及时可见」的问题，那怎么解决的呢？嗯，就是把「异步优化」给”禁用“掉（：</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：内存屏障可以分为三种类型：写屏障，读屏障以及全能屏障（包含了读写屏障），屏障可以简单理解为：在操作数据的时候，往数据插入一条”特殊的指令”。只要遇到这条指令，那前面的操作都得「完成」。</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：那写屏障就可以这样理解：CPU当发现写屏障的指令时，会把该指令「之前」存在于「store Buffer」所有写指令刷入高速缓存。</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：通过这种方式就可以让CPU修改的数据可以马上暴露给其他CPU，达到「写操作」可见性的效果。</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：那读屏障也是类似的：CPU当发现读屏障的指令时，会把该指令「之前」存在于「invalid queue」所有的指令都处理掉</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：通过这种方式就可以确保当前CPU的缓存状态是准确的，达到「读操作」一定是读取最新的效果。</p>
<p><img src="https://tva1.sinaimg.cn/large/008i3skNgy1gtv3vfcw4kj60ro0dwt9o02.jpg"></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：由于不同CPU架构的缓存体系不一样、缓存一致性协议不一样、重排序的策略不一样、所提供的内存屏障指令也有差异，为了简化Java开发人员的工作。Java封装了一套规范，这套规范就是「Java内存模型」</p>
<p><span style="color:#000080"><strong>候选者</strong></span>：再详细地说，「Java内存模型」希望 屏蔽各种硬件和操作系统的访问差异，保证了Java程序在各种平台下对内存的访问都能得到一致效果。目的是解决多线程存在的原子性、可见性（缓存一致性）以及有序性问题。</p>
<p><img src="https://tva1.sinaimg.cn/large/008i3skNgy1gtv3z24z57j60sq0ew76202.jpg"></p>
<p><span style="color:#ab4642"><strong>面试官</strong></span>：<strong>那要不简单聊聊Java内存模型的规范和内容吧？</strong></p>
<p><span style="color:#000080"><strong>候选者</strong></span>：不了，怕一聊就是一个下午，下次吧？</p>
<p><strong>本文总结</strong>：</p>
<ul>
<li>并发问题产生的三大根源是「可见性」「有序性」「原子性」</li>
<li>可见性：CPU架构下存在高速缓存，每个核心下的L1/L2高速缓存不共享（不可见）</li>
<li>有序性：主要有三方面可能导致打破<ul>
<li>编译器优化导致重排序（编译器可以在不改变单线程程序语义的情况下，可以对代码语句顺序进行调整重新排序）</li>
<li>指令集并行重排序（CPU原生就有可能将指令进行重排）</li>
<li>内存系统重排序（CPU架构下很可能有store buffer /invalid queue 缓冲区，这种「异步」很可能会导致指令重排）</li>
</ul>
</li>
<li>原子性：Java的一条语句往往需要多条 CPU 指令完成(i++)，由于操作系统的线程切换很可能导致 i++ 操作未完成，其他线程“中途”操作了共享变量  i ，导致最终结果并非我们所期待的。</li>
<li>在CPU层级下，为了解决「缓存一致性」问题，有相关的“锁”来保证，比如“总线锁”和“缓存锁”。<ul>
<li>总线锁是锁总线，对共享变量的修改在相同的时刻只允许一个CPU操作。</li>
<li>缓存锁是锁缓存行(cache line)，其中比较出名的是MESI协议，对缓存行标记状态，通过“同步通知”的方式，来实现(缓存行)数据的可见性和有序性</li>
<li>但“同步通知”会影响性能，所以会有内存缓冲区(store buffer/invalid queue)来实现「异步」进而提高CPU的工作效率</li>
<li>引入了内存缓冲区后，又会存在「可见性」和「有序性」的问题，平日大多数情况下是可以享受「异步」带来的好处的，但少数情况下，需要强「可见性」和「有序性」，只能”禁用”缓存的优化。</li>
<li>“禁用”缓存优化在CPU层面下有「内存屏障」，读屏障/写屏障/全能屏障，本质上是插入一条”屏障指令”，使得缓冲区(store buffer/invalid queue)在屏障指令之前的操作均已被处理，进而达到 读写 在CPU层面上是可见和有序的。</li>
</ul>
</li>
<li>不同的CPU实现的架构和优化均不一样，Java为了屏蔽硬件和操作系统访问内存的各种差异，提出了「Java内存模型」的规范，保证了Java程序在各种平台下对内存的访问都能得到一致效果</li>
</ul>
<p><img src="https://tva1.sinaimg.cn/large/008i3skNgy1gtm73doselj61400miaby02.jpg"></p>
<p><span align="center">第一时间获取<span style="color:#000080"><strong>BATJTMD一线互联网大厂</strong></span>最新的面试资料以及内推机会关注公众号<span style="color:#ab4642"><strong>「对线<span style="color:#ab4642"><strong>面试官</strong></span>」</strong></span></p>
<img align="center" src='https://tva1.sinaimg.cn/large/008i3skNgy1gtlvty8zo5j60u00u0q5602.jpg' width=300px height=300px />

</div>


    <div class="post-guide">
        <div class="item left">
            
              <a href="/luffy/2021/08/19/04-Java%E8%99%9A%E6%8B%9F%E6%9C%BA/01.%20Java%E7%BC%96%E8%AF%91%E5%88%B0%E6%89%A7%E8%A1%8C%E7%9A%84%E8%BF%87%E7%A8%8B/">
                  <i class="fa fa-angle-left" aria-hidden="true"></i>
                  01. Java编译到执行的过程
              </a>
            
        </div>
        <div class="item right">
            
              <a href="/luffy/2021/08/19/08-MySQL/03.%20MySQL%E8%B0%83%E4%BC%98/">
                03. MySQL调优
                <i class="fa fa-angle-right" aria-hidden="true"></i>
              </a>
            
        </div>
    </div>




<script>
	
	
</script>
	</div>
	<button id="totop-toggle" class="toggle"><i class="fa fa-angle-double-up" aria-hidden="true"></i></button>
</body>
</html>
